package com.example.demo.service.impl;

import com.example.demo.entity.Rule;
import com.example.demo.exception.BusinessException;
import com.example.demo.exception.ErrorCode;
import com.example.demo.mapper.RuleMapper;
import com.example.demo.service.RuleService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class RuleServiceImpl implements RuleService {
    private static final Logger logger = LoggerFactory.getLogger(RuleServiceImpl.class);

    @Autowired
    private RuleMapper ruleMapper;

    @Override
    @Transactional
    public Rule createRule(Rule rule) {
        logger.info("Creating new rule: {}", rule);
        
        // 检查name是否已存在
        Rule existingRule = ruleMapper.selectByName(rule.getName());
        if (existingRule != null) {
            throw new BusinessException(ErrorCode.RULE_NAME_EXIST, "菜单名称已存在");
        }

        // 检查frontpath是否已存在
        if (rule.getFrontpath() != null && !rule.getFrontpath().isEmpty()) {
            Rule existingFrontpath = ruleMapper.selectByFrontpath(rule.getFrontpath());
            if (existingFrontpath != null) {
                throw new BusinessException(ErrorCode.RULE_FRONTPATH_EXIST, "前端路径已存在");
            }
        }

        ruleMapper.insert(rule);
        return ruleMapper.selectById(rule.getId());
    }

    @Override
    @Transactional
    public boolean updateRule(Rule rule) {
        logger.info("Updating rule with id: {}", rule.getId());
        
        Rule existingRule = ruleMapper.selectById(rule.getId());
        if (existingRule == null) {
            throw new BusinessException(ErrorCode.RULE_NOT_FOUND, "菜单不存在");
        }

        // 检查name是否已存在（排除自身）
        // Rule sameNameRule = ruleMapper.selectByName(rule.getName());
        // if (sameNameRule != null && !sameNameRule.getId().equals(rule.getId())) {
        //     throw new BusinessException(ErrorCode.RULE_NAME_EXIST, "菜单名称已存在");
        // }

        // 检查frontpath是否已存在（排除自身）
        if (rule.getFrontpath() != null && !rule.getFrontpath().isEmpty()) {
            Rule sameFrontpathRule = ruleMapper.selectByFrontpath(rule.getFrontpath());
            if (sameFrontpathRule != null && !sameFrontpathRule.getId().equals(rule.getId())) {
                throw new BusinessException(ErrorCode.RULE_FRONTPATH_EXIST, "前端路径已存在");
            }
        }

        return ruleMapper.updateById(rule) > 0;
    }

    @Override
    @Transactional
    public boolean deleteRule(Integer id) {
        logger.info("Deleting rule with id: {}", id);
        
        Rule rule = ruleMapper.selectById(id);
        if (rule == null) {
            throw new BusinessException(ErrorCode.RULE_NOT_FOUND, "菜单不存在");
        }

        // 检查是否有子菜单
        List<Rule> childRules = ruleMapper.selectByRuleId(id);
        if (!childRules.isEmpty()) {
            throw new BusinessException(ErrorCode.RULE_HAS_CHILDREN, "存在子菜单，无法删除");
        }

        return ruleMapper.deleteById(id) > 0;
    }

    @Override
    public Rule getRuleById(Integer id) {
        logger.info("Getting rule by id: {}", id);
        
        Rule rule = ruleMapper.selectById(id);
        if (rule == null) {
            throw new BusinessException(ErrorCode.RULE_NOT_FOUND, "菜单不存在");
        }
        return rule;
    }

    @Override
    public PageInfo<Rule> getRuleList(Integer page, Integer size) {
        logger.info("Getting rule list, page: {}, size: {}", page, size);
        
        PageHelper.startPage(page, size);
        List<Rule> rules = ruleMapper.selectAll(null);
        return new PageInfo<>(rules);
    }

    @Override
    @Transactional
    public boolean updateRuleStatus(Integer id, Integer status) {
        logger.info("Updating rule status, id: {}, status: {}", id, status);
        
        Rule rule = ruleMapper.selectById(id);
        if (rule == null) {
            throw new BusinessException(ErrorCode.RULE_NOT_FOUND, "菜单不存在");
        }

        return ruleMapper.updateStatusById(id, status) > 0;
    }

    @Override
    @Transactional
     public List<Rule> getRuleTree(Integer menu) {
        // 获取所有规则数据
        List<Rule> rules = ruleMapper.selectAll(menu);
        // 将所有规则存入 Map，方便查找
        Map<Integer, Rule> ruleMap = new HashMap<>();
        for (Rule rule : rules) {
            ruleMap.put(rule.getId(), rule);
        }

        // 递归构建树形结构
        List<Rule> rootRules = new ArrayList<>();
        for (Rule rule : rules) {
            if (rule.getRule_id() == 0) { // 找到所有顶级节点
                rootRules.add(rule);
            } else { // 非顶级节点，递归挂载到父节点
                Rule parent = ruleMap.get(rule.getRule_id());
                if (parent != null) {
                    if (parent.getChild() == null) {
                        parent.setChild(new ArrayList<>());
                    }
                    parent.getChild().add(rule);
                }
            }
        }

        return rootRules;
    }
}
